package com.luoyuanxiangvip.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luoyuanxiangvip.common.constant.Constant;
import com.luoyuanxiangvip.common.enums.ConfigEnum;
import com.luoyuanxiangvip.common.utils.RestClientUtil;
import com.luoyuanxiangvip.common.vo.BizArticleVO;
import com.luoyuanxiangvip.common.vo.OtherOption;
import com.luoyuanxiangvip.common.vo.SiteSettings;
import com.luoyuanxiangvip.core.entity.BizArticle;
import com.luoyuanxiangvip.core.entity.BizArticleTag;
import com.luoyuanxiangvip.core.entity.BizCategory;
import com.luoyuanxiangvip.core.entity.BizTag;
import com.luoyuanxiangvip.core.mapper.BizArticleMapper;
import com.luoyuanxiangvip.core.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章 服务实现类
 * </p>
 *
 * @author luoyuanxiang <p>luoyuanxiangvip.com</p>
 * @since 2019-05-30
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BizArticleServiceImpl extends ServiceImpl<BizArticleMapper, BizArticle> implements IBizArticleService {

    @Resource
    @Lazy
    private IBizTagService iBizTagService;
    @Resource
    @Lazy
    private IBizArticleTagService iBizArticleTagService;
    @Resource
    @Lazy
    private IBizCategoryService iBizCategoryService;
    @Resource
    @Lazy
    private IConfigService iConfigService;

    /**
     * 分页
     *
     * @param bizArticleVO 分页对象
     * @return PageUtil
     */
    @Override
    public IPage<BizArticle> findPageBreakByCondition(BizArticleVO bizArticleVO) {
        return this.baseMapper.findPageBreakByCondition(new Page<BizArticle>(bizArticleVO.getPage(), bizArticleVO.getLimit()), bizArticleVO);
    }

    /**
     * 添加或修改文章
     *
     * @param article article
     * @return boolean
     */
    @Override
    public boolean insertOrUpdate(BizArticle article) {
        if (article.getId() != null) {
            // 删除 tag_id 然后在添加
            List<Long> articleTagList = iBizArticleTagService.findByArticleId(article.getId());
            iBizArticleTagService.removeByIds(articleTagList);
        }
        boolean b = this.saveOrUpdate(article);
        if (b) {
            // 添加标签
            // java 8 通过 map 转换为想要的 list
            List<BizArticleTag> bizArticleTagList = article.getTagIds().stream()
                    .map(tagId -> {
                        BizArticleTag bizArticleTag = new BizArticleTag();
                        bizArticleTag.setArticleId(article.getId());
                        bizArticleTag.setTagId(tagId);
                        return bizArticleTag;
                    })
                    .collect(Collectors.toList());
            b = iBizArticleTagService.saveBatch(bizArticleTagList);
        }
        this.refreshTag();
        this.refreshCategory();
        return b;
    }

    /**
     * 获取文章详情
     *
     * @param id     文章id
     * @param status 状态
     * @return BizArticle
     */
    @Override
    public BizArticle info(Long id, Boolean status) {
        BizArticle info = this.baseMapper.info(id, status);
        List<Long> tagIdList = new ArrayList<>();
        info.getTag().forEach(tag -> tagIdList.add(tag.getId()));
        // 用于后台标签回显
        info.setTagIds(tagIdList);
        if (status != null) {
            // 相关文章
            IPage<BizArticle> page = this.page(new Page<>(1, 10), new QueryWrapper<BizArticle>()
                    .ne("id", info.getId())
                    .and(i -> i.eq(StringUtils.isNotBlank(info.getThumb()), "thumb", info.getThumb())
                            .or()
                            .eq("category_id", info.getCategoryId())
                            .or()
                            .like("keywords", info.getTitle())
                            .or()
                            .like("comment", info.getTitle())
                            .or()
                            .like("title", info.getTitle())));
            info.setRelated(page.getRecords());
        }
        return info;
    }

    /**
     * 百度推送
     *
     * @param ids 文章id
     * @return String
     */
    @Override
    public String push(Long[] ids) {
        OtherOption otherOption = iConfigService.getValue(ConfigEnum.OTHER_OPTION.getKey());
        SiteSettings siteSettings = iConfigService.getValue(ConfigEnum.SITE_SETTINGS.getKey());
        String url = MessageFormat.format(Constant.BAIDU_LINK_PUST, siteSettings.getSiteWebUrl(), otherOption.getBaiduPushToken());
        List<String> urlList = new ArrayList<>();
        Arrays.stream(ids).forEach(id -> urlList.add(siteSettings.getSiteWebUrl() + "/article/" + id));
        return RestClientUtil.post(url, urlList);
    }

    @Async
    public void refreshTag() {
        // 重新计算标签
        List<BizTag> bizTagList = iBizTagService.list();
        bizTagList.forEach(tag -> {
            Long count = iBizArticleTagService.countByTagId(tag.getId());
            tag.setCount(count);
            iBizTagService.updateById(tag);
        });
    }

    @Async
    public void refreshCategory() {
        // 重新计算分类
        List<BizCategory> list = iBizCategoryService.list();
        list.forEach(category -> {
            Long count = this.baseMapper.countByCategoryId(category.getId());
            category.setCount(count);
            iBizCategoryService.updateById(category);
        });
    }
}
